package com.monkey.tensquare.base.service.impl;

import cn.hutool.core.util.StrUtil;
import com.monkey.tensquare.base.entity.City;
import com.monkey.tensquare.base.mapper.CityMapper;
import com.monkey.tensquare.base.service.CityService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Service
public class CityServiceImpl implements CityService {
    @Autowired
    private CityMapper cityMapper;
    @Override
    public void add(City city) {
        cityMapper.save(city);
    }

    @Override
    public List<City> findAll() {
        return cityMapper.findAll();
    }

    @Override
    public void update(String cityId, City city) {
        city.setId(cityId);
        cityMapper.save(city);
    }

    @Override
    public void delete(String cityId) {
        cityMapper.deleteById(cityId);
    }

    @Override
    public City findById(String cityId) {
        return cityMapper.findById(cityId).get();
    }

    @Override
    public List<City> search(City city) {
        Specification<City> specification = createSpecification(city);
        return cityMapper.findAll(specification);
    }

    @Override
    public PageResult<City> search(City city, Integer page, Integer size) {
        Specification<City> specification = createSpecification(city);
        Page<City> cityPage = cityMapper.findAll(specification, PageRequest.of(page - 1, size));
        return new PageResult<City>(cityPage.getTotalElements(),cityPage.getContent());
    }

    private Specification<City> createSpecification(City city) {
        return new Specification<City>() {
            @Override
            public Predicate toPredicate(Root<City> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (city != null){
                    if (StrUtil.isNotBlank(city.getName())){
                        predicateList.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + city.getName() + "%"));
                    }
                    if (StrUtil.isNotBlank(city.getIshot())){
                        predicateList.add(criteriaBuilder.equal(root.get("ishot").as(String.class), city.getIshot()));
                    }
                }
                Predicate[] predicates = new Predicate[predicateList.size()];
                predicates = predicateList.toArray(predicates);
                return criteriaBuilder.and(predicates);
            }
        };
    }
}
